#include "Task_system.h"

static bool Timer_TASK_RUN = false;
static struct Timer_TASK *pBlocked , *pSuspend;
void Timer_task(void)
{
    struct Timer_TASK *pb1= pBlocked;
    while(pb1 != NULL)
    {
        if(pb1->Time > 0)
        {
            pb1->Time --;
        }else{
            Timer_TASK_RUN = true;
        }
        pb1 = pb1->pNext;
    }
}

void Run_Timer_task(void)
{
    struct Timer_TASK *pb1= pBlocked,*pb2 = pBlocked;
    if(Timer_TASK_RUN == true)
    {
        Timer_TASK_RUN = false;
        while(pb1 != NULL)
        {
            if(pb1->Time == 0)
            {
                if(pb1->fun != NULL)    pb1->Time = pb1->fun();
                if(pb1->Time < 0)
                {
                    Task_free(pb1);
                    if(pb1 == pBlocked)    
                    {
                        pBlocked = pb1->pNext;
                    }else
                    {
                        pb2->pNext = pb1->pNext;
                        pb1 = pb1->pNext;
                        continue;
                    }
                }
            }
            pb2 = pb1;
            pb1 = pb1->pNext;
        }
    }
}

int Crate_Timer_task(u8 id ,  int (*fun)(void) , u16 time)
{
    struct Timer_TASK  *pb , *pb2;
    if(id == 0) return TASK_ERR;
    if(GetTaskAddress(id) != NULL)    return TASK_ERR;
    pb = (struct Timer_TASK *) Task_malloc (sizeof(struct Timer_TASK));    
    if(pb == NULL) return TASK_ERR;
    pb->ID = id;
    pb->Time = time;
    pb->fun = fun;
    pb->pNext = NULL;
    if(pBlocked == NULL){
        pBlocked = pb;
    }else{
        pb2 = pBlocked;
        while(pb2->pNext != NULL)
        {
            pb2 = pb2->pNext;
        }
        pb2->pNext = pb;
    }
    return TASK_OK;
}

u8 SuspendTask(u8 id)                  //将任务挂起
{
  struct Timer_TASK  *pb1,*pb2;             //本级链表指针，上一个链表指针
  pb1 = pb2 = pBlocked;
  while(pb1 != NULL)
  {
    if(pb1->ID == id)                 //寻找ID号的位置 
    {
      if(pb1 == pBlocked) pBlocked = pb1->pNext;
      else pb2->pNext = pb1->pNext;   //将上一个链表指向下一个链表，以此删除本级链表
      pb1->pNext = NULL;              //清除指向下一级的指针值 
      if(pSuspend == NULL)              //首个挂起的任务 
      {
        pSuspend = pb1;
      }else{
        pb2 = pSuspend;
        while(pb2->pNext != NULL)     //找到挂起态链表的尾指针 
        {
          pb2 = pb2->pNext;
        }
        pb2->pNext = pb1;             //添加到挂起态链表
      }
      if(pb1 == pBlocked)  pBlocked = NULL;
      return TASK_OK;
    }
    pb2 = pb1;
    pb1 = pb1->pNext;
  }
  return TASK_ERR;
}

u8 ResumeTask(u8 id , u16 time)       //恢复挂起的任务 ，ID号，任务启动的等待时间 
{
  struct Timer_TASK  *pb1,*pb2;             //本级链表指针，上一个链表指针
  pb1 = pb2 = pSuspend;
  while(pb1 != NULL)
  {
    if(pb1->ID == id)                 //寻找ID号的位置 
    {
      if(pb1 == pSuspend) pSuspend = pb1->pNext;
      else pb2->pNext = pb1->pNext;   //将上一个链表指向下一个链表，以此删除本级链表
      pb1->Time = time;               //任务启动的等待时间
      pb1->pNext = NULL;              //清除指向下一级的指针值
      if(pBlocked == NULL)            //阻塞态已无任务
      {
        pBlocked = pb1;
      }else{
        pb2 = pBlocked;
        while(pb2->pNext != NULL)     //找到阻塞态链表的尾指针
        {
          pb2 = pb2->pNext;
        }
        pb2->pNext = pb1;             //添加到挂起态链表
      }
      return TASK_OK;
    }
    pb2 = pb1;
    pb1 = pb1->pNext;
  }
  return TASK_ERR;
}

void Delete_Timer_task(u8 id)
{
    struct Timer_TASK  *pb1,*pb2;
    pb1 = pb2 = pBlocked;
    while(pb1 != NULL)
    {
        if(pb1->ID == id)    
        {
      Task_free(pb1);
            if(pb1 == pBlocked)    pBlocked = pb1->pNext;
            else pb2->pNext = pb1->pNext;    
            break;
        }
        pb2 = pb1;
        pb1 = pb1->pNext;
    }
}

struct Timer_TASK  TaskBuff[Tasks_MAX];
struct Timer_TASK *Task_malloc(u8 size)
{
    u8 i;
    for(i=0;i<Tasks_MAX;i++)
    {
        if(TaskBuff[i].fun == NULL)
        {
            return &TaskBuff[i];
        }
    }
    return NULL;
}

void Task_free(struct Timer_TASK *ptr)
{
    if(ptr == NULL)    return ;
    ptr->fun = NULL;
}

struct Timer_TASK *GetTaskAddress(u8 id)
{
    struct Timer_TASK  *pb;
    pb = pBlocked;
    while(pb != NULL)
    {
        if(pb->ID == id)    return pb;
        pb = pb->pNext;
    }
    return NULL;
}

void Set_Task_Time(u8 id , int time)    //修改任务的等待时间
{
  struct Timer_TASK  *pb;
  pb = pBlocked;
  while(pb != NULL)
  {
    if(pb->ID == id)  pb->Time = time;
    pb = pb->pNext;
  }
}
